﻿#region File and License Information
/*
<File>
	<Copyright>Copyright © 2007, Daniel Vaughan. All rights reserved.</Copyright>
	<License see="prj:///Documentation/License.txt"/>
	<Owner Name="Daniel Vaughan" Email="dbvaughan@gmail.com"/>
	<CreationDate>2009-03-22 14:02:43Z</CreationDate>
	<LastSubmissionDate>$Date: $</LastSubmissionDate>
	<Version>$Revision: $</Version>
</File>
*/
#endregion

using System;

namespace DanielVaughan
{
	/// <summary>
	/// Utility class for validating method parameters.
	/// </summary>
	public static class ArgumentValidator
	{
		/// <summary>
		/// Ensures the specified value is not null.
		/// </summary>
		/// <typeparam name="T">The type of the value.</typeparam>
		/// <param name="value">The value to test.</param>
		/// <param name="parameterName">Name of the parameter.</param>
		/// <returns>The specified value.</returns>
		/// <exception cref="ArgumentNullException">Occurs if the specified value 
		/// is <code>null</code>.</exception>
		public static T AssertNotNull<T>(T value, string parameterName) where T : class
		{
			if (value == null)
			{
				throw new ArgumentNullException(parameterName);
			}

			return value;
		}

		/// <summary>
		/// Ensures the specified value is not <code>null</code> or empty (a zero length string).
		/// </summary>
		/// <param name="value">The value to test.</param>
		/// <param name="parameterName">Name of the parameter.</param>
		/// <returns>The specified value.</returns>
		/// <exception cref="ArgumentNullException">Occurs if the specified value 
		/// is <code>null</code> or empty (a zero length string).</exception>
		public static string AssertNotNullOrEmpty(string value, string parameterName)
		{
			if (value == null)
			{
				throw new ArgumentNullException(parameterName);
			}

			if (value.Length < 1)
			{
				throw new ArgumentException("Parameter should not be an empty string.", parameterName); /* TODO: Make localizable resource. */
			}

			return value;
		}

		/// <summary>
		/// Ensures the specified value is not <code>null</code> 
		/// and that it is of the specified type.
		/// </summary>
		/// <param name="value">The value to test.</param> 
		/// <param name="parameterName">The name of the parameter.</param>
		/// <returns>The value to test.</returns>
		/// <exception cref="ArgumentNullException">Occurs if the specified value 
		/// is <code>null</code> or of type not assignable from the specified type.</exception>
		/// <example>
		/// public DoSomething(object message)
		/// {
		/// 	this.message = ArgumentValidator.AssertNotNullAndOfType&lt;string&gt;(message, "message");	
		/// }
		/// </example>
		public static T AssertNotNullAndOfType<T>(object value, string parameterName) where T : class
		{
			if (value == null)
			{
				throw new ArgumentNullException(parameterName);
			}
			var result = value as T;
			if (result == null)
			{
				throw new ArgumentException(string.Format(
					"Expected argument of type " + typeof(T) + ", but was " + value.GetType(), typeof(T), value.GetType()),
					parameterName);
			}
			return result;
		}

		/* TODO: [DV] Comment. */
		public static int AssertGreaterThan(int value, int greaterThan, string parameterName)
		{
			if (value < greaterThan)
			{
				throw new ArgumentOutOfRangeException("Parameter should be greater than " + greaterThan, parameterName); /* TODO: Make localizable resource. */
			}
			return value;
		}

		/* TODO: [DV] Comment. */
		public static double AssertGreaterThan(double value, double mustBeGreaterThan, string parameterName)
		{
			if (value < mustBeGreaterThan)
			{
				throw new ArgumentOutOfRangeException("Parameter should be greater than " + mustBeGreaterThan, parameterName); /* TODO: Make localizable resource. */
			}
			return value;
		}

		/* TODO: [DV] Comment. */
		public static double AssertLessThan(double value, double mustBeLessThan, string parameterName)
		{
			if (value > mustBeLessThan)
			{
				throw new ArgumentOutOfRangeException("Parameter should be less than " + mustBeLessThan, parameterName); /* TODO: Make localizable resource. */
			}
			return value;
		}

		/* TODO: [DV] Comment. */
		public static long AssertGreaterThan(long value, long mustBeGreaterThan, string parameterName)
		{
			if (value < mustBeGreaterThan)
			{
				throw new ArgumentOutOfRangeException("Parameter should be greater than " + mustBeGreaterThan, parameterName); /* TODO: Make localizable resource. */
			}
			return value;
		}
	}
}

